/**
 * HEIG-VD
 * MCR - Projet "Pandemie"
 * Auteurs: Thierry Forchelet, Louis Jaquier, Grégory Moinat, Julien Rebetez
 */

package app;

import java.util.Vector;

import visitable.Chicken;
import visitable.ConnectionManager;
import visitable.Creature;
import visitable.Human;
import visitable.Pig;

/**
 * Représentation d'un monde cruel rempli de créatures et de visiteurs
 */
public class World {

	private Vector<Creature> creatures = new Vector<Creature>();
	// Le monde est perçu comme une grille. Les créatures sont voisines entre elles si elles
	// se touchent dans la grille
	private int gridSize; // Le nombre de créature sur une ligne de la grille

	/**
	 * Constructeur
	 * @param gridSize la taille de la grille
	 */
	public World(int gridSize) {
		this.gridSize = gridSize;
		final int nbCreatures = gridSize * gridSize;

		/* Création des créatures */
		for (int i = 0; i < nbCreatures; i++) {
			double r = Math.random();
			if (r < 0.3)
				creatures.add(new Human());
			else if (r - 0.3 < 0.3)
				creatures.add(new Pig());
			else
				creatures.add(new Chicken());
		}
		
		/**
		 * Créatino des liaisons
		 * 
		 * Cas général de liaison, une creature C est liee a ses voisines A,B,D,E
		 *     A
		 *   B C D
		 *     E
		 *  Si l'indice de C est i, les indices des voisins sont :
		 *  A => i - gridsize
		 *  B => i-1
		 *  D => i+1
		 *  E => i + gridsize
		 *  
		 *  Cas spéciaux ou on ne créer pas de lien pour ne pas sortir du monde :
		 *   => A < 0
		 *   => E >= nbCreatures
		 *   => B/gridsize != i/gridSize (B sur la ligne precedente)
		 *   => D/gridsize != i/gridSize (D sur la ligne suivante)
		 *  
		 *  Mais puisque les liens sont __bidirectionnels__, on ne doit en fait lier que sur D et E
		 */
		final ConnectionManager connManager = ConnectionManager.getInstance();
		for (int i = 0; i < nbCreatures; i++) {
		  final int D = i + 1;
		  final int E = i + gridSize;
		  if (E < nbCreatures)
		    connManager.addConnection(creatures.elementAt(i), creatures.elementAt(E));
      if (D/gridSize == i/gridSize)
        connManager.addConnection(creatures.elementAt(i), creatures.elementAt(D));
		}
	}

	/**
	 * @return La liste des créatures de ce monde
	 */
	public Vector<Creature> getCreatures() {
		return creatures;
	}
	
	
	/**
	 * @return Le nombre d'éléments sur une ligne de la grille du monde
	 */
	public int getGridSize() {
		return gridSize;
	}
	
	/**
	 * @return Le nombre de créatures au total
	 */
	public int getNbCreature () {
		return gridSize*gridSize;
	}
}
